package com.lee.enjoy221113_retrofit;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;

import okhttp3.Call;
import okhttp3.FormBody;
import okhttp3.HttpUrl;
import okhttp3.Request;

/**
 * @ProjectName: LifeCycleTest
 * @Package: com.lee.enjoy221113_retrofit
 * @ClassName: ServiceMethod
 * @Description: java类作用描述
 * @Author: 李占伟
 * @CreateDate: 2022/11/14 15:10
 * @UpdateUser: 更新者
 * @UpdateDate: 2022/11/14 15:10
 * @UpdateRemark: 更新说明
 * @Version: 1.0
 */

public class ServiceMethod {

    private HttpUrl baseUrl ;
    private final String httpMethod;
    private final String relativeUrl;
    private final boolean hasBody;
    ParameterHandler[] parameterHandler;
    private FormBody.Builder formBuild;//表单提交

    private  HttpUrl.Builder urlbuild;

    private final Call.Factory  callFactory;
    public ServiceMethod(Builder builder) {
        this.httpMethod = builder.httpMethod;
        relativeUrl = builder.relativeUrl;
        this.hasBody = builder.hasBody;
        callFactory = builder.enjoyRetrofit.callFactory;
        parameterHandler = builder.parameterHandler;
        this.baseUrl = builder.enjoyRetrofit.baseUrl;
        //如果是有请求体  ，用okhttp的请求体对象
        if (hasBody){
            formBuild = new FormBody.Builder();
        }
    }

    public Object invoke(Object[] args){
        for (int i = 0; i < parameterHandler.length; i++) {
            ParameterHandler handlers = parameterHandler[i];
            handlers.apply(this,args[i].toString());
        }
        HttpUrl url;
        if (urlbuild==null){
            urlbuild = baseUrl.newBuilder(relativeUrl);
        }
        url = urlbuild.build();
        FormBody formBody = null;
        if (formBuild!=null){
            formBody = formBuild.build();
        }
        Request request = new Request.Builder().url(url).method(httpMethod, formBody).build();
        return callFactory.newCall(request);
    }

    //把k-v 放到请求体 POST请求
    public void addFieldParameter(String key, String value) {
        formBuild.add(key, value);

    }
    //把k-v 放到请求头 url里面
    public void addQueryParameter(String key, String value) {
        if (urlbuild==null){
            urlbuild = baseUrl.newBuilder(relativeUrl);
        }
        urlbuild.addQueryParameter(key,value);
    }

    public static class Builder{

        private final EnjoyRetrofit enjoyRetrofit;
        private final Annotation[] methodAnnotations;
        private final  Annotation[][] parameterAnnotations;
        private String httpMethod="";
        private String relativeUrl="";
        private boolean hasBody = false;
        ParameterHandler[] parameterHandler;

        public Builder(EnjoyRetrofit enjoyRetrofit1, Method method) {
            enjoyRetrofit = enjoyRetrofit1;
            //获取方法上的多有的注解
            methodAnnotations = method.getAnnotations();
            //获取方法参数上的所有注解 二维数组  一个参数可以有多个注解
             parameterAnnotations = method.getParameterAnnotations();
        }

        public ServiceMethod build(){

            for (Annotation annotation:methodAnnotations){
                if (annotation instanceof POST){
                    this.httpMethod = "POST";
                    this.relativeUrl = ((POST) annotation).value();
                    this.hasBody = true;

                }else if (annotation instanceof GET){
                    this.httpMethod = "GET";
                    this.relativeUrl = ((GET) annotation).value();
                    this.hasBody = false;
                }else{

                }
            }
            int length = parameterAnnotations.length;
            parameterHandler = new ParameterHandler[length];
            for (int i = 0; i < length; i++) {
                //得到一个参数上的所有注解
                Annotation[] parameterAnnotation = parameterAnnotations[i];
                for (Annotation annotation:parameterAnnotation){
                    if (annotation instanceof FIELD){
                        if (this.httpMethod.equals("GET")){
                            throw new RuntimeException("Get请求不能使用FILED注解");
                        }
                        //请求参数 key
                        String value = ((FIELD) annotation).value();
                        parameterHandler[i] = new ParameterHandler.FieldParameterHandler(value);
                    }
                    if (annotation instanceof QUERY){
                        if (this.httpMethod.equals("POST")){
                            throw new RuntimeException("Post请求不能使用QUERY注解");
                        }
                        String value = ((QUERY) annotation).value();
                        parameterHandler[i] = new ParameterHandler.QueryParameterHandler(value);
                    }
                }
            }
            return new ServiceMethod(this);
        }


    }
}
